package com.geostar.constructionland.attachment.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.geostar.constructionland.attachment.entity.*;
import com.geostar.constructionland.attachment.entity.vo.UploadPreVo;
import com.geostar.constructionland.attachment.mapper.GeoAttachmentMapper;
import com.geostar.constructionland.attachment.service.IAttachmentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @author : yell
 * @Description: 文件controller
 * @date : 2020/12/29 16:31
 */
@Controller
@Slf4j
@RequestMapping("/file")
public class FileController {
    @Autowired
    GeoAttachmentMapper geoAttachmentMapper;

    private IAttachmentService uploadFileService;
    private WebUploaderOption webUploaderOption;

    @Autowired
    public void setUploadFileService(IAttachmentService uploadFileService) {
        this.uploadFileService = uploadFileService;
    }

    /**
     * 分片上传
     *
     * @param geoAttachment
     * @return
     */
    @RequestMapping(value = "/uploadChunk")
    @ResponseBody
    public RepEntity uploadChunk(@Valid GeoAttachment geoAttachment, MultipartFile file) throws Exception{
        // 赋值
        geoAttachment.setFileContent(file.getBytes());
        return uploadFileService.uploadByChunks(geoAttachment);
    }

    @RequestMapping(value = "/upload")
    @ResponseBody
    public RepEntity upload(@Valid GeoAttachment geoAttachment, MultipartFile file) throws Exception {
        // 文件大小校验
        if(webUploaderOption.getChunkedHoldSize() <= file.getSize()){
            throw new Exception("上传文件大小大于分片阈值,请使用分片上传");
        }
        // md5校验
        String tmpMd5 = DigestUtils.md5Hex(file.getBytes());
        log.info("tmpMd5:{},jsMd5：{}",tmpMd5, geoAttachment.getMd5());
        if(!tmpMd5.equals(geoAttachment.getMd5())){
            throw new Exception("md5不一致,请重新上传");
        }
        // 赋值
        geoAttachment.setFileContent(file.getBytes());
        return uploadFileService.upload(geoAttachment);
    }

    @RequestMapping(value = "/uploadOffice")
    @ResponseBody
    public RepEntity uploadOffice(@Valid GeoAttachment geoAttachment, MultipartFile file) throws Exception {
        // 文件大小校验
        if(webUploaderOption
                .getChunkedHoldSize() <= file.getSize()){
            throw new Exception("上传文件大小大于分片阈值,请使用分片上传");
        }
        // md5校验
        String tmpMd5 = DigestUtils.md5Hex(file.getBytes());
        log.info("tmpMD5:{},MD5:{}",tmpMd5,geoAttachment.getMd5());
        if(!tmpMd5.equals(geoAttachment.getMd5())){
            throw new Exception("md5不一致,请重新上传");
        }
        // 赋值
        geoAttachment.setFileContent(file.getBytes());
        return uploadFileService.uploadWordAndTranToPdf(geoAttachment);
    }

    /**
     * 合并分片
     *
     * @param geoAttachment
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/mergeChunk")
    @ResponseBody
    public RepEntity mergeChunk(GeoAttachment geoAttachment) throws Exception {
        List<GeoAttachment> list =
                geoAttachmentMapper.selectList(new LambdaQueryWrapper<GeoAttachment>()
                                                .eq(GeoAttachment::getMd5, geoAttachment.getMd5()));
        if (CollectionUtils.isNotEmpty(list)) {
            return new RepEntity("200", "秒传,不需要合并");
        }
        long size = geoAttachment.getFileSize();
        int chunkSize = geoAttachment.getChunkSize();
        double doubleChunks = (double) size / (double) chunkSize;
        int chunks = (int) Math.ceil(doubleChunks);
        geoAttachment.setChunks(chunks);
        return uploadFileService.mergeChunks(geoAttachment);
    }

    /**
     * 上传前预处理信息
     *
     * @param geoAttachment 百度上传组件实体
     * @return
     */
    @RequestMapping("/getUploadPreInfo")
    @ResponseBody
    public UploadPreVo getUploadPreInfo(GeoAttachment geoAttachment) {
        UploadPreVo uploadPreVo = uploadFileService.preUpload(geoAttachment);
        return uploadPreVo;
    }

    /**
     * 下载文件
     */
    @RequestMapping("/downloadFile")
    public void downloadFile(@NotEmpty(message = "附件ID不能为空") String attachId, HttpServletResponse response) throws Exception {
        FileDownVo fileDownVo = uploadFileService.downLoadFile(attachId);
        response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileDownVo.getFileName(), "UTF-8"));
        response.setCharacterEncoding("UTF-8");
        ServletOutputStream outputStream = null;
        try {
            outputStream = response.getOutputStream();
            outputStream.write(fileDownVo.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 获取上传组件部分配置
     *
     * @return
     */
    @RequestMapping("/getWebUploaderOption")
    @ResponseBody
    public WebUploaderOption getWebUploaderOption() {
        return webUploaderOption;
    }

    @Autowired
    public void setWebUploaderOption(WebUploaderOption webUploaderOption) {
        this.webUploaderOption = webUploaderOption;
    }

}
